package com.ajieee.merge.runner.finance;

import cn.idev.excel.FastExcel;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.read.listener.ReadListener;
import com.ajieee.merge.entity.finance.po.StockInfoPO;
import com.ajieee.merge.enums.finance.EtlType;
import com.ajieee.merge.enums.finance.Exchange;
import com.ajieee.merge.mapper.StockInfoMapper;
import com.ajieee.merge.runner.finance.dto.StockInfoExcelModel;
import lombok.RequiredArgsConstructor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.client.RestClient;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ajieee
 * @date 2025-10-13
 */
@Order(EtlOrder.INFO_ORDER)
@Component
@RequiredArgsConstructor
public class SzseStockInfoEtl extends AbstractEtl {

	private final RestClient restClient;

	private final StockInfoMapper stockInfoMapper;

	@Override
	public void doExecute() {
		String uriString = UriComponentsBuilder.fromUriString("https://www.szse.cn/api/report/ShowReport")
				.queryParam("SHOWTYPE", "xlsx")
				.queryParam("CATALOGID", "1110")
				.queryParam("TABKEY", "tab1")
				.build().encode().toUriString();
		byte[] respBytes = restClient.get()
				.uri(uriString)
				.retrieve()
				.body(byte[].class);
		Assert.notNull(respBytes, "请求深证股票A基本信息错误");

		List<StockInfoPO> pos = new ArrayList<>();
		try (InputStream inputStream = new ByteArrayInputStream(respBytes)) {
			FastExcel.read(inputStream, StockInfoExcelModel.class, new ReadListener<StockInfoExcelModel>() {
				@Override
				public void invoke(StockInfoExcelModel data, AnalysisContext context) {
					StockInfoPO po = new StockInfoPO();
					po.setStockCode(data.getAStockCode());
					po.setStockName(data.getAStockName());
					po.setExchange(Exchange.SZSE);
					po.setAStockCode(data.getAStockCode());
					po.setBStockCode(data.getBStockCode());
					po.setListDate(data.getAListDate());
					po.setStockType(deduceStockType(data.getBlock(), "A"));
					po.setCompanyCode(data.getAStockCode());
					po.setCompanyNameFull(data.getCompanyNameFull());
					po.setCompanyNameEnFull(data.getCompanyNameEnFull());
					po.setAreaName(data.getProvince() + data.getCity());
					po.setIndustry(handleIndustry(data.getIndustry()));

					pos.add(po);
				}

				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
				}
			}).doReadAll();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		// 深证B股
		uriString = UriComponentsBuilder.fromUriString("https://www.szse.cn/api/report/ShowReport")
				.queryParam("SHOWTYPE", "xlsx")
				.queryParam("CATALOGID", "1110")
				.queryParam("TABKEY", "tab2")
				.build().encode().toUriString();
		respBytes = restClient.get()
				.uri(uriString)
				.retrieve()
				.body(byte[].class);
		Assert.notNull(respBytes, "请求深证股票B基本信息错误");
		try (InputStream inputStream = new ByteArrayInputStream(respBytes)) {
			FastExcel.read(inputStream, StockInfoExcelModel.class, new ReadListener<StockInfoExcelModel>() {
				@Override
				public void invoke(StockInfoExcelModel data, AnalysisContext context) {
					StockInfoPO po = new StockInfoPO();
					po.setStockCode(data.getBStockCode());
					po.setStockName(data.getBStockName());
					po.setExchange(Exchange.SZSE);
					po.setAStockCode(data.getAStockCode());
					po.setBStockCode(data.getBStockCode());
					po.setListDate(data.getBListDate());
					po.setStockType(deduceStockType(data.getBlock(), "B"));
					po.setCompanyCode(data.getAStockCode() == null ? data.getBStockCode() : data.getAStockCode());
					po.setCompanyNameFull(data.getCompanyNameFull());
					po.setCompanyNameEnFull(data.getCompanyNameEnFull());
					po.setAreaName(data.getProvince() + data.getCity());
					po.setIndustry(handleIndustry(data.getIndustry()));

					pos.add(po);
				}

				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
				}
			}).doReadAll();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		if (!pos.isEmpty()) {
			stockInfoMapper.deleteByExchange(Exchange.SZSE);
			stockInfoMapper.insert(pos);
		}

	}

	private String handleIndustry(String industry) {
		if (industry == null) {
			return "未知";
		}
		String[] arr = industry.split(" ");
		if (arr.length == 2) {
			return arr[1].trim();
		}
		return industry;
	}

	private String deduceStockType(String block, String type) {
		if ("主板".equals(block)) {
			return "A".equals(type) ? "主板A股" : "主板B股";
		} else {
			return "科创板";
		}
	}

	@Override
	public EtlType getType() {
		return EtlType.SZSE_STOCK_INFO;
	}
}
